package com.javacoo.xservice.base;

import java.util.Map;
import java.util.Optional;
import java.util.function.Function;

import javax.servlet.http.HttpServletResponse;

import org.springframework.web.bind.annotation.RequestMapping;

import com.javacoo.xservice.base.config.Resources;
import com.javacoo.xservice.base.exception.IllegalParameterException;
import com.javacoo.xservice.base.support.swaparea.SwapAreaUtils;
import com.javacoo.xservice.base.utils.WebUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * 业务参数控制器基类
 * <p>说明:</p>
 * <li>定义有业务参数的接口处理基本流程</li>
 * @author DuanYong
 * @since 2017年6月28日下午2:48:27
 */
@Slf4j
public abstract class AbstractUrlParamController extends BaseController {
	/**
	 * 接口处理
	 * <p>说明:</p>
	 * <li>1:请求参数解析</li>
	 * <li>2:检查请求参数</li>
	 * <li>3:业务处理</li>
	 * <li>4:设置响应数据</li>
	 * @author DuanYong
	 * @since 2017年6月28日下午3:19:43
	 */
	@RequestMapping
	public final void handle(HttpServletResponse response) {
		Long startTime = System.currentTimeMillis();
        //参数解析->检查请求参数->业务处理->设置响应数据
        parse().map(r->validateFunction.apply(r)).map(r->Optional.ofNullable(execute(r))).map(o->setSuccessResponse(response,o.orElse(Optional.empty())));
		log.info("[{}]接口->{},处理完成,耗时->{}秒",SwapAreaUtils.getSwapAreaData().getTransactionSn(), SwapAreaUtils.getSwapAreaData().getReqMethod(),(System.currentTimeMillis() - startTime)/1000.0);
	}
	/**
	 * 执行
	 * <p>说明:</p>
	 * @author DuanYong
	 * @param p 请求参数
	 * @return Object 业务返回数据
	 * @since 2017年11月13日下午3:41:04
	 */
	private final Object execute(Map<String,String> p){
		return executeFunction.apply(p);
	}
	/**
	 * 解析请求参数
	 * <p>说明:</p>
	 * <li>将URL请求参数中的业务参数对象转换为服务使用的MAP对象</li>
	 * @author DuanYong
	 * @since 2017年6月28日下午3:17:32
     * @return: java.util.Optional<Map<String,String>> 业务参数对象
	 */
	protected final Optional<Map<String,String>> parse(){
		BaseRequest baseRequest = SwapAreaUtils.getSwapAreaData().getBaseRequest();
		if(baseRequest.getQueryStringMap().isEmpty()){
			log.error("解析URL请求参数失败，请求参数为空,流水号:{}", WebUtil.getSwapAreaData().getTransactionSn());
			throw new IllegalParameterException(Resources.getMessage(ErrorCodeConstants.COMMON_REQ_PARAM_PARSE_IS_EMPTY));
		}
		return Optional.ofNullable(baseRequest.getQueryStringMap());

	}
	/**
	 * 校验请求中的业务参数
	 * <p>说明:</p>
	 * <li>由子类实现，如果参数检查不通过，请抛出参数异常:IllegalParameterException</li>
	 * @author DuanYong
	 * @param p 业务参数对象
	 * @throws IllegalParameterException
	 * @since 2017年6月28日下午2:28:10
	 */
	protected abstract void validate(Map<String,String> p) throws IllegalParameterException;
	/**
	 * 具体业务处理
	 * <p>说明:</p>
	 * <li>由子类实现</li>
	 * @author DuanYong
	 * @param p 业务参数对象
	 * @return 业务返回数据
	 * @since 2017年5月5日下午3:24:09
	 */
	protected abstract Object process(Map<String,String> p);
	/**
	 * 校验并返回业务参数
	 */
	private Function<Map<String,String>,Map<String,String>> validateFunction = (Map<String,String> p)->{
		validate(p);
		return p;
	};
	/**
	 * 执行业务处理
	 */
	private Function<Map<String,String>,Object> executeFunction = (Map<String,String> p)-> process(p);
}
